<template><div><p>本文档最新版为 <a href="https://learnku.com/docs/laravel/10.x" target="_blank" rel="noopener noreferrer">10.x</a>，旧版本可能放弃维护，推荐阅读最新版！</p>
<h2 id="laravel-测试之-数据库测试" tabindex="-1"><a class="header-anchor" href="#laravel-测试之-数据库测试"><span>Laravel 测试之 - 数据库测试</span></a></h2>
<ul>
<li><a href="#introduction">简介</a></li>
<li><a href="#resetting-the-database-after-each-test">每次测试后重置数据库</a></li>
<li><a href="#writing-factories">创建模型工厂</a>
<ul>
<li><a href="#factory-states">工厂状态</a></li>
</ul>
</li>
<li><a href="#using-factories">在测试中使用模型工厂</a>
<ul>
<li><a href="#creating-models">创建模型</a></li>
<li><a href="#persisting-models">持久化模型</a></li>
<li><a href="#relationships">模型关联</a></li>
</ul>
</li>
<li><a href="#available-assertions">可用的断言方法</a></li>
</ul>
<h2 id="简介" tabindex="-1"><a class="header-anchor" href="#简介"><span>简介</span></a></h2>
<p>Laravel 提供了多种有用的工具来让你更容易的测试使用数据库的应用程序。首先，你可以使用 <code v-pre>assertDatabaseHas</code> 辅助函数，来断言数据库中是否存在与指定条件互相匹配的数据。举例来说，如果我们想验证 <code v-pre>users</code> 数据表中是否存在 <code v-pre>email</code> 值为 <code v-pre>sally@example.com</code> 的数据，我们可以按照以下的方式来做测试：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">testDatabase</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// 创建调用至应用程序...</span></span>
<span class="line"></span>
<span class="line">    <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">assertDatabaseHas</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'users'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'email'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'sally@example.com'</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>你也可以使用 <code v-pre>assertDatabaseMissing</code> 辅助函数来断言数据不在数据库中。</p>
<p>当然，使用 <code v-pre>assertDatabaseHas</code> 方法及其它的辅助函数只是为了方便。你也可以随意使用 PHPUnit 内置的所有断言方法来扩充测试。</p>
<h2 id="每次测试后重置数据库" tabindex="-1"><a class="header-anchor" href="#每次测试后重置数据库"><span>每次测试后重置数据库</span></a></h2>
<p>在每次测试后重新设置数据库通常很有用，这样以前测试的数据不会干扰后续的测试。<code v-pre>RefreshDatabase</code> trait 会采用最优的方法来迁移你的测试数据库，这取决于你使用的是内存数据库还是传统数据库。在你的测试类中简单地引用这个 trait，一切都将为你处理：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">Tests<span class="token punctuation">\</span>Feature</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Tests<span class="token punctuation">\</span>TestCase</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Foundation<span class="token punctuation">\</span>Testing<span class="token punctuation">\</span>RefreshDatabase</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Foundation<span class="token punctuation">\</span>Testing<span class="token punctuation">\</span>WithoutMiddleware</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">ExampleTest</span> <span class="token keyword">extends</span> <span class="token class-name">TestCase</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">use</span> <span class="token package">RefreshDatabase</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 一个基本的功能测试示例。</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">void</span></span></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">testBasicExample</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token variable">$response</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">        <span class="token comment">// ...</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="创建模型工厂" tabindex="-1"><a class="header-anchor" href="#创建模型工厂"><span>创建模型工厂</span></a></h2>
<p>测试时，常常需要在运行测试之前写入一些数据到数据库中。创建测试数据时，除了手动的来设置每个字段的值，还可以使用 <a href="https://learnku.com/docs/laravel/5.5/eloquent" target="_blank" rel="noopener noreferrer">Eloquent 模型</a> 的「工厂」来设置每个属性的默认值。在开始之前，你可以先查看下应用程序的 <code v-pre>database/factories/UserFactory.php</code> 文件。此文件包含了一个现成的模型工厂定义：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$factory</span><span class="token operator">-></span><span class="token function">define</span><span class="token punctuation">(</span><span class="token class-name class-name-fully-qualified static-context">App<span class="token punctuation">\</span>User</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token class-name class-name-fully-qualified type-declaration">Faker<span class="token punctuation">\</span>Generator</span> <span class="token variable">$faker</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">static</span> <span class="token variable">$password</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'name'</span> <span class="token operator">=></span> <span class="token variable">$faker</span><span class="token operator">-></span><span class="token property">name</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'email'</span> <span class="token operator">=></span> <span class="token variable">$faker</span><span class="token operator">-></span><span class="token function">unique</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token property">safeEmail</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'password'</span> <span class="token operator">=></span> <span class="token variable">$password</span> <span class="token operator">?</span><span class="token punctuation">:</span> <span class="token variable">$password</span> <span class="token operator">=</span> <span class="token function">bcrypt</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'secret'</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'remember_token'</span> <span class="token operator">=></span> <span class="token function">str_random</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>在作为工厂定义的闭包中，你可以返回模型上所有属性的默认测试值。 闭包将接收 PHP 函数库 <a href="https://github.com/fzaninotto/Faker" target="_blank" rel="noopener noreferrer">Faker</a> 的一个实例，它允许你方便地生成各种随机数据进行测试。</p>
<p>为了更好的组织代码，你也可以自己为每个数据模型创建对应的模型工厂类。例如，你可以在 <code v-pre>database/factories</code> 目录下创建 <code v-pre>UserFactory.php</code> 和 <code v-pre>CommentFactory.php</code> 文件。 Laravel 将会自动加载 <code v-pre>factories</code> 目录下的所有文件。</p>
<h3 id="工厂状态" tabindex="-1"><a class="header-anchor" href="#工厂状态"><span>工厂状态</span></a></h3>
<p>工厂状态可以让你任意组合你的模型工厂，仅需要做出适当差异化的修改，就可以达到让模型拥有多种不同的状态。例如，你的 <code v-pre>用户</code> 模型中可以修改某个默认属性值来达到标识一种 <code v-pre>欠款</code> 的状态。你可以使用 <code v-pre>state</code> 方法来进行这种状态转换。对于简单的工厂状态，你可以直接传入要修改的属性数组。</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$factory</span><span class="token operator">-></span><span class="token function">state</span><span class="token punctuation">(</span><span class="token class-name class-name-fully-qualified static-context">App<span class="token punctuation">\</span>User</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'delinquent'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'account_status'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'delinquent'</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果你的工厂状态需要计算或者需要使用 <code v-pre>$faker</code> 实例，你可以使用闭包方法来实现状态属性的修改：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$factory</span><span class="token operator">-></span><span class="token function">state</span><span class="token punctuation">(</span><span class="token class-name class-name-fully-qualified static-context">App<span class="token punctuation">\</span>User</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'address'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$faker</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'address'</span> <span class="token operator">=></span> <span class="token variable">$faker</span><span class="token operator">-></span><span class="token property">address</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="在测试中使用模型工厂" tabindex="-1"><a class="header-anchor" href="#在测试中使用模型工厂"><span>在测试中使用模型工厂</span></a></h2>
<h3 id="创建模型" tabindex="-1"><a class="header-anchor" href="#创建模型"><span>创建模型</span></a></h3>
<p>在模型工厂定义后，就可以在测试或是数据库的填充文件中，通过全局的 <code v-pre>factory</code> 函数来生成模型实例。接着让我们先来看看几个创建模型的例子。首先我们会使用 <code v-pre>make</code> 方法创建模型，但不将它们保存至数据库：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">testDatabase</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token variable">$user</span> <span class="token operator">=</span> <span class="token function">factory</span><span class="token punctuation">(</span><span class="token class-name class-name-fully-qualified static-context">App<span class="token punctuation">\</span>User</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">make</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token comment">// 在测试中使用模型...</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>你也可以创建一个含有多个模型的集合，或创建一个指定类型的模型：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token comment">// 创建一个 App\User 实例</span></span>
<span class="line"><span class="token variable">$users</span> <span class="token operator">=</span> <span class="token function">factory</span><span class="token punctuation">(</span><span class="token class-name class-name-fully-qualified static-context">App<span class="token punctuation">\</span>User</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">make</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="应用模型工厂状态" tabindex="-1"><a class="header-anchor" href="#应用模型工厂状态"><span>应用模型工厂状态</span></a></h4>
<p>你可能需要在你的模型中应用不同的 <a href="#factory-states">模型工厂状态</a>。如果你想模型加上多种不同的状态，你只须指定每个你想添加的状态名称即可：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$users</span> <span class="token operator">=</span> <span class="token function">factory</span><span class="token punctuation">(</span><span class="token class-name class-name-fully-qualified static-context">App<span class="token punctuation">\</span>User</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">states</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'delinquent'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">make</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$users</span> <span class="token operator">=</span> <span class="token function">factory</span><span class="token punctuation">(</span><span class="token class-name class-name-fully-qualified static-context">App<span class="token punctuation">\</span>User</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">states</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'premium'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'delinquent'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">make</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="重写模型属性" tabindex="-1"><a class="header-anchor" href="#重写模型属性"><span>重写模型属性</span></a></h4>
<p>如果你想重写模型中的某些默认值，则可以传递一个包含数值的数组至 <code v-pre>make</code> 方法。只有指定的数值会被替换，其它剩余的数值则会按照模型工厂指定的默认值来设置：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$user</span> <span class="token operator">=</span> <span class="token function">factory</span><span class="token punctuation">(</span><span class="token class-name class-name-fully-qualified static-context">App<span class="token punctuation">\</span>User</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">make</span><span class="token punctuation">(</span><span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'name'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'Abigail'</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="持久化模型" tabindex="-1"><a class="header-anchor" href="#持久化模型"><span>持久化模型</span></a></h3>
<p><code v-pre>create</code> 方法不仅会创建模型实例，同时会使用 Eloquent 的 <code v-pre>save</code> 方法来将它们保存至数据库：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">testDatabase</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// 创建一个 App\User 实例</span></span>
<span class="line">    <span class="token variable">$user</span> <span class="token operator">=</span> <span class="token function">factory</span><span class="token punctuation">(</span><span class="token class-name class-name-fully-qualified static-context">App<span class="token punctuation">\</span>User</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token comment">// 创建 3 个 App\User 实例</span></span>
<span class="line">    <span class="token variable">$users</span> <span class="token operator">=</span> <span class="token function">factory</span><span class="token punctuation">(</span><span class="token class-name class-name-fully-qualified static-context">App<span class="token punctuation">\</span>User</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token comment">// 在测试中使用模型...</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>同样的，你可以在数组传递至 <code v-pre>create</code> 方法时重写模型的属性</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$user</span> <span class="token operator">=</span> <span class="token function">factory</span><span class="token punctuation">(</span><span class="token class-name class-name-fully-qualified static-context">App<span class="token punctuation">\</span>User</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'name'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'Abigail'</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="模型关联" tabindex="-1"><a class="header-anchor" href="#模型关联"><span>模型关联</span></a></h3>
<p>在本例中，我们还会增加关联至我们所创建的模型。当使用 <code v-pre>create</code> 方法创建多个模型时，它会返回一个 Eloquent <a href="https://learnku.com/docs/laravel/5.5/eloquent-collections" target="_blank" rel="noopener noreferrer">集合实例</a>，让你能够使用集合所提供的便利函数，像是 <code v-pre>each</code>：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$users</span> <span class="token operator">=</span> <span class="token function">factory</span><span class="token punctuation">(</span><span class="token class-name class-name-fully-qualified static-context">App<span class="token punctuation">\</span>User</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span></span>
<span class="line">           <span class="token operator">-></span><span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">           <span class="token operator">-></span><span class="token function">each</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$u</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">                <span class="token variable">$u</span><span class="token operator">-></span><span class="token function">posts</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">save</span><span class="token punctuation">(</span><span class="token function">factory</span><span class="token punctuation">(</span><span class="token class-name class-name-fully-qualified static-context">App<span class="token punctuation">\</span>Post</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">make</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">            <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="关联和属性闭包" tabindex="-1"><a class="header-anchor" href="#关联和属性闭包"><span>关联和属性闭包</span></a></h4>
<p>你可以使用闭包参数来创建模型关联。例如你想在创建一个 <code v-pre>Post</code> 时顺便创建一个 <code v-pre>User</code> 实例，可以这样定义：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$factory</span><span class="token operator">-></span><span class="token function">define</span><span class="token punctuation">(</span><span class="token class-name class-name-fully-qualified static-context">App<span class="token punctuation">\</span>Post</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$faker</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'title'</span> <span class="token operator">=></span> <span class="token variable">$faker</span><span class="token operator">-></span><span class="token property">title</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'content'</span> <span class="token operator">=></span> <span class="token variable">$faker</span><span class="token operator">-></span><span class="token property">paragraph</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'user_id'</span> <span class="token operator">=></span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">            <span class="token keyword">return</span> <span class="token function">factory</span><span class="token punctuation">(</span><span class="token class-name class-name-fully-qualified static-context">App<span class="token punctuation">\</span>User</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token property">id</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token punctuation">}</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>这些闭包也可以获取到生成的模型工厂包含的属性数组：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$factory</span><span class="token operator">-></span><span class="token function">define</span><span class="token punctuation">(</span><span class="token class-name class-name-fully-qualified static-context">App<span class="token punctuation">\</span>Post</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$faker</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'title'</span> <span class="token operator">=></span> <span class="token variable">$faker</span><span class="token operator">-></span><span class="token property">title</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'content'</span> <span class="token operator">=></span> <span class="token variable">$faker</span><span class="token operator">-></span><span class="token property">paragraph</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'user_id'</span> <span class="token operator">=></span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">            <span class="token keyword">return</span> <span class="token function">factory</span><span class="token punctuation">(</span><span class="token class-name class-name-fully-qualified static-context">App<span class="token punctuation">\</span>User</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token property">id</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token punctuation">}</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'user_type'</span> <span class="token operator">=></span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token keyword type-hint">array</span> <span class="token variable">$post</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">            <span class="token keyword">return</span> <span class="token class-name class-name-fully-qualified static-context">App<span class="token punctuation">\</span>User</span><span class="token operator">::</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token variable">$post</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'user_id'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token property">type</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token punctuation">}</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="可用的断言方法" tabindex="-1"><a class="header-anchor" href="#可用的断言方法"><span>可用的断言方法</span></a></h2>
<p>Laravel 为你的 <a href="https://phpunit.de/" target="_blank" rel="noopener noreferrer">PHPUnit</a> 测试提供了一些数据库断言方法：</p>
<table>
<thead>
<tr>
<th>方法名</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td><code v-pre>$this-&gt;assertDatabaseHas($table, array $data);</code></td>
<td>断言数据库里含有指定数据。</td>
</tr>
<tr>
<td><code v-pre>$this-&gt;assertDatabaseMissing($table, array $data);</code></td>
<td>断言表里没有指定数据。</td>
</tr>
<tr>
<td><code v-pre>$this-&gt;assertSoftDeleted($table, array $data);</code></td>
<td>断言指定记录已经被软删除。</td>
</tr>
</tbody>
</table>
<h2 id="译者署名" tabindex="-1"><a class="header-anchor" href="#译者署名"><span>译者署名</span></a></h2>
<table>
<thead>
<tr>
<th>用户名</th>
<th>头像</th>
<th>职能</th>
<th>签名</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://github.com/limxx" target="_blank" rel="noopener noreferrer">@limxx</a></td>
<td><img src="https://avatars0.githubusercontent.com/u/16585030?v=4&amp;s=400" alt="16585030?v=4&amp;s=400"></td>
<td>翻译</td>
<td>Winter is coming.</td>
</tr>
</tbody>
</table>
<hr>
<blockquote>
<p>{note} 欢迎任何形式的转载，但请务必注明出处，尊重他人劳动共创开源社区。</p>
<p>转载请注明：本文档由 Laravel China 社区 <a href="https://laravel-china.org/" target="_blank" rel="noopener noreferrer">laravel-china.org</a> 组织翻译，详见 <a href="https://learnku.com/laravel/t/5756/laravel-55-document-translation-call-come-and-join-the-translation" target="_blank" rel="noopener noreferrer">翻译召集帖</a>。</p>
<p>文档永久地址： <a href="https://learnku.com/docs/laravel" target="_blank" rel="noopener noreferrer">《Laravel 中文文档》</a></p>
</blockquote>
</div></template>


